<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CodeMirror编辑器的使用</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    html, body {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    .editor-box {
      width: 800px;
      height: 600px;
    }
  </style>

</head>

<body>
  <div id="editor" class="editor-box"></div>

  <script type="module">
    // 编辑器状态，描述当前编辑器使用的插件，文本等信息
    // import { EditorState, type, Extension, Compartment, StateEffect } from "@codemirror/state";
    // import { EditorView } from "@codemirror/view";
    // import { basicSetup } from "codemirror";
    import { EditorState, type, Extension, Compartment, StateEffect } from "../node_modules/@codemirror/state/dist/index.js";
    import { EditorView, keymap } from "../node_modules/@codemirror/view/dist/index.js";
    import { basicSetup } from "../node_modules/codemirror/dist/index.js";
    import { defaultKeymap } from "../node_modules/@codemirror/commands/dist/index.js"

    /**
     * 创建一个compartment,并和对其修改的run函数
     * @param view
     * @returns
     */
    // https://codemirror.net/examples/config/
    // https://github.com/uiwjs/react-codemirror/blob/22cc81971a/src/useCodeMirror.ts#L144
    // https://gist.github.com/s-cork/e7104bace090702f6acbc3004228f2cb

    const createEditorCompartment = () => {
      const compartment = new Compartment();
      const run = (extension, view) => {
        // 判断当前编辑器中是否存在当前的compartment封装过的插件
        if (compartment.get(view.state)) {
          // 动态地重新配置插件
          view.dispatch({
            effects: compartment.reconfigure(extension)
          });   // reconfigure
        } else {
          // 向编辑器注入某一个插件
          view.dispatch({
            effects: StateEffect.appendConfig.of(compartment.of(extension))
          });  // inject
        }

      }
      return { compartment, run };
    }

    // 动态语言包函数
    // let { compartment, run } = createEditorCompartment();
    let editor = null;
    // const updateLang = (lang) => {
    //   // 根据语言名称匹配语言描述信息
    //   const languageDescription = LanguageDescription.matchLanguageName(languages, 'java', true);
    //   // 注入高亮插件
    //   languageDescription.load().then(support => {
    //     run(support, editor)
    //   })
    // }

    let element = document.getElementById('editor');
    // 创建编辑器状态
    let state = EditorState.create({
      doc: "Hello world!", // 初始文本
      // 传入的插件数组
      // extensions: [
      //   basicSetup
      // ]
      extensions: [
        keymap.of(defaultKeymap)
      ]
    });
    let view = new EditorView({
      state: state,   // 编辑器状态，编辑器视图创建时初始化的状态
      // parent: element // 挂载的dom，可以通过parent挂载到指定的div块
      parent: document.body // 挂载的dom，可以通过parent挂载到指定的div块
    });
    editor = view;

  </script>
</body>

</html>